/* 
 * File:   Processor.cpp
 * Author: max
 * 
 * Created on April 8, 2013, 11:25 PM
 */
#include <iostream>
#include <sstream>
#include <fstream>
#include "Processor.h"
#include "UnitOfWorkParser.h"

using namespace TP3::Working;

Processor::Processor(const char* rulesPath, const char* inPutPath,const char* outPutPath){

    std::stringstream aux;
    aux << rulesPath;
    aux >> _rulesPath;

    aux.clear();
    aux << inPutPath;
    aux >> _inPutPath;
    
    aux.clear();
    aux << outPutPath;
    aux >> _outPutPath;
    
    _inPut = NULL;
    _outPut = NULL;
}

Processor::~Processor() {

    finilizeInput();
    finilizeOutPut();
}

void Processor::Process () throw (int){
    
    try
    {
        initInput ();
        initOutPut();
        
        UnitOfWorkParser parser;
        UnitOfWork* work = parser.parse(_rulesPath, ';', _outPut);
        
        if (work != NULL)
        {
            string operating;
            
            while (!_inPut->eof())
            {
                *_inPut >> operating;
                
                if (operating.length() > 0)
                    work->apply(operating);
                
                operating = "";
            }
            delete work;
        }
        
        finilizeInput();
        finilizeOutPut();
    }
    catch (int ex)
    {
        finilizeInput();
        finilizeOutPut();
        
        if (INPUT_FILE_ERROR == ex || OUTPUT_FILE_ERROR == ex || IO_ERROR == ex)
            throw ex;
    }
}

void Processor::initInput () throw (int){

    if ("-" == _inPutPath)
    {
        _inPut = &cin;
    }
    else
    {
        ifstream* file = new ifstream (_inPutPath.c_str());
        
        if (file != NULL)
        {
            if (!file->is_open())
                throw INPUT_FILE_ERROR;

            _inPut = (istream*) file;
        }
        else
            throw MEM_ERROR;
    }
}

void Processor::initOutPut () throw (int){
    
    if ("-" == _outPutPath)
        _outPut = &cout;
    else
    {
        ofstream* file = new ofstream (_outPutPath.c_str());
        
        if (file != NULL)
        {
            if (!file->is_open())
                throw OUTPUT_FILE_ERROR;

            _outPut = (ostream*) file;
        }
        else
            throw MEM_ERROR;
    }
}

void Processor::finilizeInput() throw (int){

    if ("-" != _inPutPath)
    {
        if (NULL != _inPut)
        {
            delete _inPut;
            _inPut = NULL;
        }
    }
}

void Processor::finilizeOutPut() throw (int){
    
    if ("-" != _outPutPath)
    {
        if (NULL != _outPut)
        {
            delete _outPut;
            _outPut = NULL;
        }
    }
}


